<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="vgAE5" id="vgAE5"><span data-lake-id="u925ea96a" id="u925ea96a">典型回答</span></h1>
  <p data-lake-id="u41fcfb19" id="u41fcfb19"><br></p>
  <p data-lake-id="u365a8a70" id="u365a8a70"><span data-lake-id="u2141907e" id="u2141907e">有的时候，我们需要实现这样的功能，比如说我们有多个黑名单需要校验，为了提升效率，需要并发执行，执行过程中，如果有结果先返回了，就判断他是否命中了黑名单，如果命中，则不用再等后续的其他请求了，直接拒绝即可，否则就要等所有的请求都返回，所有的返回都是通过，返回通过。</span></p>
  <p data-lake-id="u85466f76" id="u85466f76"><span data-lake-id="uf3e280a7" id="uf3e280a7">​</span><br></p>
  <p data-lake-id="ue1a916a9" id="ue1a916a9"><span data-lake-id="u4409d19b" id="u4409d19b">想要实现这个功能，可以借助</span><strong><span data-lake-id="u0a0d6b94" id="u0a0d6b94">CompletionService</span></strong><span data-lake-id="ua39f3bee" id="ua39f3bee">。</span></p>
  <p data-lake-id="u91f692da" id="u91f692da"><br></p>
  <p data-lake-id="u2e605303" id="u2e605303"><span data-lake-id="u25c8c4c5" id="u25c8c4c5">CompletionService是Java8的新增接口，JDK为其提供了一个实现类ExecutorCompletionService。这个类是为线程池中Task的执行结果服务的，即为Executor中Task返回Future而服务的。</span></p>
  <p data-lake-id="uf9de0817" id="uf9de0817"><span data-lake-id="u11d3540d" id="u11d3540d">​</span><br></p>
  <p data-lake-id="ued1fe378" id="ued1fe378"><strong><span data-lake-id="u9eaa34d2" id="u9eaa34d2">CompletionService的实现目标是任务先完成可优先获取到，即结果按照完成先后顺序排序。</span></strong></p>
  <p data-lake-id="ub2a9377c" id="ub2a9377c"><span data-lake-id="uf6fcd0ad" id="uf6fcd0ad">​</span><br></p>
  <p data-lake-id="ud1d90413" id="ud1d90413"><span data-lake-id="ub47a7df1" id="ub47a7df1">​</span><br></p>
  <p data-lake-id="u9cf23959" id="u9cf23959" style="text-align: center"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1691563743569-69729c6a-2b53-4e64-86fc-923314824ef0.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_26%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="ue7c5a87c" id="ue7c5a87c" style="text-align: center"><br></p>
  <p data-lake-id="u2ff73e68" id="u2ff73e68" style="text-align: left"><span data-lake-id="u0818fc7c" id="u0818fc7c">主要的代码实现如下：</span></p>
  <p data-lake-id="u56c797fb" id="u56c797fb" style="text-align: center"><br></p>
  <pre lang="java"><code>
//先创建一个线程池
ScheduledExecutorService blackListCheckExecutorService = new ScheduledThreadPoolExecutor(20,
            new BasicThreadFactory.Builder().namingPattern("multi-black-list-decision-%d").build());
            
//定义一个CompletionService，返回值为boolean类型 
CompletionService&lt;Boolean&gt; completionService = new ExecutorCompletionService&lt;&gt;(blackListCheckExecutorService);

//把要执行的任务提交给completionService
for (String blackListName : multiBlackListDecisionObject.getBlackListNames()) {
    completionService.submit(() -&gt; getData(new BlackListDecisionObject(multiBlackListDecisionObject, blackListName)) != null);
}

try {
    int tasks = multiBlackListDecisionObject.getBlackListNames().size();
  	//再循环中不断尝试get返回结构
    while (tasks &gt; 0) {
        Future&lt;Boolean&gt; future = completionService.take();
        boolean result = future.get();
      	//拿到一个结果后就判断是否为true
      	//只要有一个为true直接返回true
        if (result) {
            return true;
        }

        tasks--;
    }
  	//都执行完之后，没有true，则最终返回一次false
    return false;
} catch (InterruptedException | ExecutionException e) {
    return false;
}
</code></pre>
 </body>
</html>